package com.meida.student.app.listener;

import com.alibaba.fastjson.util.TypeUtils;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.utils.DateUtils;
import com.meida.module.bus.client.entity.BusAfterservice;
import com.meida.module.bus.client.entity.BusOrder;
import com.meida.module.bus.client.enums.OrderStateYEnum;
import com.meida.module.bus.client.enums.OrderStateZEnum;
import com.meida.module.bus.client.enums.OrderTypeEnum;
import com.meida.module.bus.client.enums.RedisKeyEnum;
import com.meida.module.bus.provider.service.BusAfterserviceService;
import com.meida.module.bus.provider.service.BusOrderAnswerService;
import com.meida.module.bus.provider.service.BusOrderService;
import com.meida.module.system.provider.service.SysExpireStrategyService;
import com.meida.module.user.client.entity.AppUser;
import com.meida.module.user.provider.service.AppUserService;
import com.meida.msg.client.entity.MsgReceive;
import com.meida.msg.provider.service.MsgReceiveService;
import lombok.extern.slf4j.Slf4j;
import org.openxmlformats.schemas.drawingml.x2006.chart.STGrouping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.Date;

@Component
@Slf4j
public class RedisKeyExpireListener extends KeyExpirationEventMessageListener {

    @Autowired
    private BusOrderAnswerService busOrderAnswerService;

    @Autowired
    private BusAfterserviceService busAfterserviceService;

    @Autowired
    private SysExpireStrategyService sysExpireStrategyService;

    @Autowired
    private MsgReceiveService msgReceiveService;

    @Autowired
    private BusOrderService busOrderService;

    @Autowired
    private AppUserService appUserService;

    public RedisKeyExpireListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 注意：我们只能获取到失效的 key 而获取不到 value，
        // 所以在设计 key 的时候可以考虑把 value 一并放到 key，然后根据规则取出 value
        String redisKey = new String(message.getBody());
        log.info("过期redisKey:-------------" + redisKey);
        if (redisKey.contains(RedisKeyEnum.OrderAnswerId.getRedisKey())) {
            log.info("处理答案审核通过后结算佣金给学霸" + redisKey);
            String key = redisKey.split(RedisKeyEnum.OrderAnswerId.getRedisKey())[1];
            busOrderAnswerService.orderAnswerSettleCommission(TypeUtils.castToLong(key));
            sysExpireStrategyService.deleteByRedisKey(redisKey);
        }
        if (redisKey.contains(RedisKeyEnum.OrderCancel.getRedisKey())) {
            log.info("处理订单取消的情况" + redisKey);
            String key = redisKey.split(RedisKeyEnum.OrderCancel.getRedisKey())[1];
            BusOrder busOrder = busOrderService.getById(key);
            if (FlymeUtils.isNotEmpty(busOrder)) {
                Integer orderType = busOrder.getOrderType();
                if (OrderTypeEnum.BookingTutoring.getValue().equals(orderType)) {
                    String orderState = busOrder.getOrderState();
                    //走申请售后
                    if (OrderStateYEnum.OrderState1.getValue().equals(orderState)) {
                        busAfterserviceService.applyBusAfterservice(TypeUtils.castToLong(key));
                    }
                }
                if (OrderTypeEnum.HomeWork.getValue().equals(orderType)) {
                    String orderState = busOrder.getOrderState();
                    //作业无忧还是待出价,订单取消,不涉及退款
                    if (OrderStateZEnum.OrderState1.getValue().equals(orderState)) {
                        busOrderService.updateOrderState(TypeUtils.castToLong(key), "0");
                    }
                }
                sysExpireStrategyService.deleteByRedisKey(redisKey);
            }
        }
        //处理学霸接单未上课的订单
        if (redisKey.contains(RedisKeyEnum.OrderCsCancel.getRedisKey())) {
            String key = redisKey.split(RedisKeyEnum.OrderCsCancel.getRedisKey())[1];
            BusOrder busOrder = busOrderService.getById(key);
            if (FlymeUtils.isNotEmpty(busOrder)) {
                String orderState = busOrder.getOrderState();
                //走申请售后
                if (OrderStateYEnum.OrderState2.getValue().equals(orderState)) {
                    busAfterserviceService.applyBusAfterservice(TypeUtils.castToLong(key));
                    Long userId = busOrder.getUserId();
                    Long answerUserId = busOrder.getAnswerUserId();
                    Integer orderType = busOrder.getOrderType();
                    sendNoticeToUser(userId, orderType, "{0}超时未开课通知", "您的{0}超过预约开课时间学霸未进行上课,该订单自动发起售后处理!感谢您使用留同学APP.");
                    sendNoticeToAnswerUser(answerUserId, orderType, "{0}超时未开课处罚通知", "您接受的{0}订单超过预约开课时间未进行上课，平台特此发送处罚警告通知！");
                }

            }
        }
        if (redisKey.contains(RedisKeyEnum.OrderNotice.getRedisKey())) {
            log.info("处理订单通知的情况" + redisKey);
            String key = redisKey.split(RedisKeyEnum.OrderNotice.getRedisKey())[1];
            BusOrder busOrder = busOrderService.getById(key);
            if (FlymeUtils.isNotEmpty(busOrder)) {
                String orderState = busOrder.getOrderState();
                //订单状态已取消
                if (!"0".equals(orderState)) {
                    Integer orderType = busOrder.getOrderType();
                    if (OrderTypeEnum.BookingTutoring.getValue().equals(orderType)) {
                        String appointmentDateStr = busOrder.getAppointmentDate();
                        String appointmentTimeStr = busOrder.getAppointmentTime();
                        String appointmentDateTimeStr = appointmentDateStr + " " + appointmentTimeStr + ":00";
                        String nowDateTimeStr = DateUtils.getDateTime();
                        if (!OrderStateYEnum.OrderState1.equals(orderState) && DateUtils.lt(appointmentDateTimeStr, nowDateTimeStr)) {
                            Long userId = busOrder.getUserId();
                            Long answerUserId = busOrder.getAnswerUserId();
                            sendNoticeToUser(userId, orderType, "{0},待上课通知", "您预约的{0}马上就要上课了，请您提前进行直播间！感谢您使用留同学APP");
                            sendNoticeToAnswerUser(answerUserId, userId, orderType, "{0},待上课通知", "【{0}】的{1}马上就要上课了，请您提前登录PC网站进入直播间授课！感谢您使用留同学APP");
                        }
                    }
                }
            }
            sysExpireStrategyService.deleteByRedisKey(redisKey);
        }
    }

    /**
     * 发送消息给用户
     *
     * @param userId
     * @param orderType
     * @param msgTitle
     * @param msgContent
     */
    private void sendNoticeToUser(Long userId, Integer orderType, String msgTitle, String msgContent) {
        OrderTypeEnum orderTypeEnum = OrderTypeEnum.getByValue(orderType);
        String orderTypeDesc = orderTypeEnum.getLabel();
        String title = MessageFormat.format(msgTitle, orderTypeDesc);
        String content = MessageFormat.format(msgContent, orderTypeDesc);
        MsgReceive msgReceive = msgReceiveService.sendMsgReceiveNotice(BusOrder.class.getSimpleName(), userId, title, content);
        busOrderService.orderPushMessage(msgReceive, title, content);
    }

    private void sendNoticeToAnswerUser(Long answerUserId, Long userId, Integer orderType, String msgTitle, String msgContent) {
        AppUser appUser = appUserService.getById(userId);
        if (FlymeUtils.isNotEmpty(appUser)) {
            String nickName = appUser.getNickName();
            OrderTypeEnum orderTypeEnum = OrderTypeEnum.getByValue(orderType);
            String orderTypeDesc = orderTypeEnum.getLabel();
            String title = MessageFormat.format(msgTitle, orderTypeDesc);
            String content = MessageFormat.format(msgContent, nickName, orderTypeDesc);
            MsgReceive msgReceive = msgReceiveService.sendMsgReceiveNotice(BusOrder.class.getSimpleName(), answerUserId, title, content);
            busOrderService.orderPushMessage(msgReceive, title, content);
        }
    }

    private void sendNoticeToAnswerUser(Long answerUserId,Integer orderType, String msgTitle, String msgContent) {
        OrderTypeEnum orderTypeEnum = OrderTypeEnum.getByValue(orderType);
        String orderTypeDesc = orderTypeEnum.getLabel();
        String title = MessageFormat.format(msgTitle, orderTypeDesc);
        String content = MessageFormat.format(msgContent, orderTypeDesc);
        MsgReceive msgReceive = msgReceiveService.sendMsgReceiveNotice(BusOrder.class.getSimpleName(), answerUserId, title, content);
        busOrderService.orderPushMessage(msgReceive, title, content);

    }
}
